using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;

namespace ProcessManagementApi.Controllers
{
    /// <summary>
    /// 文件上传控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class FileUploadController : ControllerBase
    {
        private readonly IWebHostEnvironment _environment;
        private readonly ILogger<FileUploadController> _logger;
        
        /// <summary>
        /// 允许的图片文件扩展名
        /// </summary>
        private readonly string[] _allowedImageExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp" };
        
        /// <summary>
        /// 允许的附件文件扩展名
        /// </summary>
        private readonly string[] _allowedDocumentExtensions = { ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".txt", ".zip", ".rar" };
        
        /// <summary>
        /// 最大文件大小（10MB）
        /// </summary>
        private const long MaxFileSize = 10 * 1024 * 1024;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="environment">Web环境</param>
        /// <param name="logger">日志记录器</param>
        public FileUploadController(IWebHostEnvironment environment, ILogger<FileUploadController> logger)
        {
            _environment = environment;
            _logger = logger;
        }

        /// <summary>
        /// 上传单个图片文件
        /// </summary>
        /// <param name="file">图片文件</param>
        /// <returns>上传结果</returns>
        [HttpPost("image")]
        public async Task<IActionResult> UploadImage([Required] IFormFile file)
        {
            try
            {
                var result = await ValidateAndSaveFile(file, _allowedImageExtensions, "images");
                if (result.Success)
                {
                    return Ok(new
                    {
                        success = true,
                        message = "图片上传成功",
                        data = new
                        {
                            fileName = result.FileName,
                            originalName = result.OriginalName,
                            filePath = result.FilePath,
                            fileUrl = result.FileUrl,
                            fileSize = result.FileSize,
                            uploadTime = result.UploadTime
                        }
                    });
                }
                else
                {
                    return BadRequest(new
                    {
                        success = false,
                        message = result.ErrorMessage
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "图片上传失败");
                return StatusCode(500, new
                {
                    success = false,
                    message = "图片上传失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 上传单个附件文件
        /// </summary>
        /// <param name="file">附件文件</param>
        /// <returns>上传结果</returns>
        [HttpPost("attachment")]
        public async Task<IActionResult> UploadAttachment([Required] IFormFile file)
        {
            try
            {
                var result = await ValidateAndSaveFile(file, _allowedDocumentExtensions, "attachments");
                if (result.Success)
                {
                    return Ok(new
                    {
                        success = true,
                        message = "附件上传成功",
                        data = new
                        {
                            fileName = result.FileName,
                            originalName = result.OriginalName,
                            filePath = result.FilePath,
                            fileUrl = result.FileUrl,
                            fileSize = result.FileSize,
                            uploadTime = result.UploadTime
                        }
                    });
                }
                else
                {
                    return BadRequest(new
                    {
                        success = false,
                        message = result.ErrorMessage
                    });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "附件上传失败");
                return StatusCode(500, new
                {
                    success = false,
                    message = "附件上传失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 批量上传图片
        /// </summary>
        /// <param name="files">图片文件列表</param>
        /// <returns>上传结果</returns>
        [HttpPost("images/batch")]
        public async Task<IActionResult> UploadImages([Required] List<IFormFile> files)
        {
            try
            {
                if (files.Count > 10)
                {
                    return BadRequest(new
                    {
                        success = false,
                        message = "一次最多只能上传10个图片文件"
                    });
                }

                var results = new List<object>();
                var errors = new List<string>();

                foreach (var file in files)
                {
                    var result = await ValidateAndSaveFile(file, _allowedImageExtensions, "images");
                    if (result.Success)
                    {
                        results.Add(new
                        {
                            fileName = result.FileName,
                            originalName = result.OriginalName,
                            filePath = result.FilePath,
                            fileUrl = result.FileUrl,
                            fileSize = result.FileSize,
                            uploadTime = result.UploadTime
                        });
                    }
                    else
                    {
                        errors.Add($"{file.FileName}: {result.ErrorMessage}");
                    }
                }

                return Ok(new
                {
                    success = true,
                    message = $"成功上传{results.Count}个文件" + (errors.Count > 0 ? $"，{errors.Count}个文件失败" : ""),
                    data = new
                    {
                        successFiles = results,
                        errors = errors
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量图片上传失败");
                return StatusCode(500, new
                {
                    success = false,
                    message = "批量图片上传失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 批量上传附件
        /// </summary>
        /// <param name="files">附件文件列表</param>
        /// <returns>上传结果</returns>
        [HttpPost("attachments/batch")]
        public async Task<IActionResult> UploadAttachments([Required] List<IFormFile> files)
        {
            try
            {
                if (files.Count > 10)
                {
                    return BadRequest(new
                    {
                        success = false,
                        message = "一次最多只能上传10个附件文件"
                    });
                }

                var results = new List<object>();
                var errors = new List<string>();

                foreach (var file in files)
                {
                    var result = await ValidateAndSaveFile(file, _allowedDocumentExtensions, "attachments");
                    if (result.Success)
                    {
                        results.Add(new
                        {
                            fileName = result.FileName,
                            originalName = result.OriginalName,
                            filePath = result.FilePath,
                            fileUrl = result.FileUrl,
                            fileSize = result.FileSize,
                            uploadTime = result.UploadTime
                        });
                    }
                    else
                    {
                        errors.Add($"{file.FileName}: {result.ErrorMessage}");
                    }
                }

                return Ok(new
                {
                    success = true,
                    message = $"成功上传{results.Count}个文件" + (errors.Count > 0 ? $"，{errors.Count}个文件失败" : ""),
                    data = new
                    {
                        successFiles = results,
                        errors = errors
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量附件上传失败");
                return StatusCode(500, new
                {
                    success = false,
                    message = "批量附件上传失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="type">文件类型（images/attachments）</param>
        /// <returns>文件流</returns>
        [HttpGet("download")]
        public async Task<IActionResult> DownloadFile([Required] string fileName, [Required] string type)
        {
            try
            {
                if (type != "images" && type != "attachments")
                {
                    return BadRequest(new
                    {
                        success = false,
                        message = "文件类型参数错误，只能是images或attachments"
                    });
                }

                var uploadsPath = Path.Combine(_environment.WebRootPath, "uploads", type);
                var filePath = Path.Combine(uploadsPath, fileName);

                if (!System.IO.File.Exists(filePath))
                {
                    return NotFound(new
                    {
                        success = false,
                        message = "文件不存在"
                    });
                }

                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                var contentType = GetContentType(fileName);

                return File(fileBytes, contentType, fileName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "文件下载失败: {FileName}", fileName);
                return StatusCode(500, new
                {
                    success = false,
                    message = "文件下载失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="type">文件类型（images/attachments）</param>
        /// <returns>删除结果</returns>
        [HttpDelete("delete")]
        public IActionResult DeleteFile([Required] string fileName, [Required] string type)
        {
            try
            {
                if (type != "images" && type != "attachments")
                {
                    return BadRequest(new
                    {
                        success = false,
                        message = "文件类型参数错误，只能是images或attachments"
                    });
                }

                var uploadsPath = Path.Combine(_environment.WebRootPath, "uploads", type);
                var filePath = Path.Combine(uploadsPath, fileName);

                if (!System.IO.File.Exists(filePath))
                {
                    return NotFound(new
                    {
                        success = false,
                        message = "文件不存在"
                    });
                }

                System.IO.File.Delete(filePath);

                return Ok(new
                {
                    success = true,
                    message = "文件删除成功"
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "文件删除失败: {FileName}", fileName);
                return StatusCode(500, new
                {
                    success = false,
                    message = "文件删除失败，请稍后重试"
                });
            }
        }

        /// <summary>
        /// 验证并保存文件
        /// </summary>
        /// <param name="file">上传的文件</param>
        /// <param name="allowedExtensions">允许的文件扩展名</param>
        /// <param name="subFolder">子文件夹名称</param>
        /// <returns>上传结果</returns>
        private async Task<FileUploadResult> ValidateAndSaveFile(IFormFile file, string[] allowedExtensions, string subFolder)
        {
            // 验证文件是否为空
            if (file == null || file.Length == 0)
            {
                return new FileUploadResult { Success = false, ErrorMessage = "请选择要上传的文件" };
            }

            // 验证文件大小
            if (file.Length > MaxFileSize)
            {
                return new FileUploadResult { Success = false, ErrorMessage = $"文件大小不能超过{MaxFileSize / 1024 / 1024}MB" };
            }

            // 验证文件扩展名
            var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
            if (!allowedExtensions.Contains(extension))
            {
                return new FileUploadResult 
                { 
                    Success = false, 
                    ErrorMessage = $"不支持的文件格式，只允许：{string.Join(", ", allowedExtensions)}" 
                };
            }

            // 创建上传目录
            var uploadsPath = Path.Combine(_environment.WebRootPath, "uploads", subFolder);
            if (!Directory.Exists(uploadsPath))
            {
                Directory.CreateDirectory(uploadsPath);
            }

            // 生成唯一文件名
            var fileName = $"{Guid.NewGuid()}{extension}";
            var filePath = Path.Combine(uploadsPath, fileName);

            // 保存文件
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            // 构建文件URL
            var fileUrl = $"/uploads/{subFolder}/{fileName}";

            return new FileUploadResult
            {
                Success = true,
                FileName = fileName,
                OriginalName = file.FileName,
                FilePath = filePath,
                FileUrl = fileUrl,
                FileSize = file.Length,
                UploadTime = DateTime.Now
            };
        }

        /// <summary>
        /// 根据文件扩展名获取Content-Type
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns>Content-Type</returns>
        private string GetContentType(string fileName)
        {
            var extension = Path.GetExtension(fileName).ToLowerInvariant();
            return extension switch
            {
                ".jpg" or ".jpeg" => "image/jpeg",
                ".png" => "image/png",
                ".gif" => "image/gif",
                ".bmp" => "image/bmp",
                ".webp" => "image/webp",
                ".pdf" => "application/pdf",
                ".doc" => "application/msword",
                ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                ".xls" => "application/vnd.ms-excel",
                ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                ".ppt" => "application/vnd.ms-powerpoint",
                ".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                ".txt" => "text/plain",
                ".zip" => "application/zip",
                ".rar" => "application/x-rar-compressed",
                _ => "application/octet-stream"
            };
        }
    }

    /// <summary>
    /// 文件上传结果
    /// </summary>
    public class FileUploadResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string? ErrorMessage { get; set; }

        /// <summary>
        /// 文件名（系统生成的唯一名称）
        /// </summary>
        public string? FileName { get; set; }

        /// <summary>
        /// 原始文件名
        /// </summary>
        public string? OriginalName { get; set; }

        /// <summary>
        /// 文件完整路径
        /// </summary>
        public string? FilePath { get; set; }

        /// <summary>
        /// 文件访问URL
        /// </summary>
        public string? FileUrl { get; set; }

        /// <summary>
        /// 文件大小（字节）
        /// </summary>
        public long FileSize { get; set; }

        /// <summary>
        /// 上传时间
        /// </summary>
        public DateTime UploadTime { get; set; }
    }
} 